package com.chc.web.user.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chc.config.jwt.JwtUtils;
import com.chc.utils.Msg;
import com.chc.web.live_user.entity.LiveUser;
import com.chc.web.live_user.service.LiveUserService;
import com.chc.web.menu.entity.MakeMenuTree;
import com.chc.web.menu.entity.Menu;
import com.chc.web.menu.entity.RouterVO;
import com.chc.web.menu.service.MenuService;
import com.chc.web.user.entity.*;
import com.chc.web.user.handler.user.LoginTypeHandler;
import com.chc.web.user.handler.user.UserTypeHandlerFactory;
import com.chc.web.user.service.UserService;
import com.chc.web.user_role.entity.UserRole;
import com.chc.web.user_role.mapper.UserRoleMapper;
import com.chc.web.user_role.service.UserRoleService;
import io.jsonwebtoken.Claims;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.DigestUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA
 *
 * @Author: chc
 * @Date: 2021/12/19/21:29
 * @Description:
 */

@RestController
@RequestMapping("/api/user")
public class UserController {

    //注入userService实现类
    @Autowired
    private UserService userService;

    @Autowired
    private UserRoleService userRoleService;

    //注入token实现类
    @Autowired
    private JwtUtils jwtUtils;

    @Resource
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private MenuService menuService;

    @Autowired
    private LiveUserService liveUserService;

    @Autowired
    private UserTypeHandlerFactory userTypeHandlerFactory;


    /**
     * 重置密码
     * */
    @PostMapping("/resetPassword")
    public Msg resetPassword(@RequestBody ChangePassword user,HttpServletRequest request){
        String token = request.getHeader("token");
        Claims claims = jwtUtils.getClaimsFromToken(token);
        //判断用户类型
        String userType = (String) claims.get("userType");
        LoginTypeHandler handler = userTypeHandlerFactory.getUserTypeHandler(userType);
        return handler.resetPwd(user);
        // if (userType.equals("0")){ //0:业主
        //     LiveUser liveUser = liveUserService.getById(user.getUserId());
        //     //原来的密码
        //     String oldPassword = liveUser.getPassword();
        //     boolean encode = passwordEncoder.matches(user.getOldPassWord(), oldPassword);
        //     if (!encode){
        //         return  Msg.error("旧密码错误");
        //     }
        //     LiveUser liveUser1 = new LiveUser();
        //     liveUser1.setUserId(user.getUserId());
        //     liveUser1.setPassword(passwordEncoder.encode(user.getNewPassWord()));
        //     boolean b = liveUserService.updateById(liveUser1);
        //     if (b){
        //         return Msg.success("密码修改成功!");
        //     }
        //     return Msg.error("密码修改失败");
        // }else {
        //     User liveUser = userService.getById(user.getUserId());
        //     //原来的密码
        //     String oldPassword = liveUser.getPassword();
        //     boolean encode = passwordEncoder.matches(user.getOldPassWord(), oldPassword);
        //     if (!encode){
        //         return  Msg.error("旧密码错误");
        //     }
        //     User liveUser1 = new User();
        //     liveUser1.setUserId(user.getUserId());
        //     liveUser1.setPassword(passwordEncoder.encode(user.getNewPassWord()));
        //     boolean b = userService.updateById(liveUser1);
        //     if (b){
        //         return Msg.success("密码修改成功!");
        //     }
        //     return Msg.error("密码修改失败");
        // }
    }

    /**
     * 退出登陆
     * */
    @PostMapping("/loginOut")
    public Msg logonOut(HttpServletRequest request, HttpServletResponse response){
        //获取用户相关信息
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication !=null){
            //清空用户信息
            new SecurityContextLogoutHandler().logout(request,response,authentication);
        }
        return Msg.success("退出登录成功!");
    }

    /**
     *
     * */
    @GetMapping("/getMenuList")
    public Msg getMenuList(HttpServletRequest request){
        //从头部获取token
        String token = request.getHeader("token");
        Claims claims = jwtUtils.getClaimsFromToken(token);
        //获取用户名
        String username = jwtUtils.getUsernameFromToken(token);
        //获取用户类型
        String userType = (String) claims.get("userType");
        LoginTypeHandler handler = userTypeHandlerFactory.getUserTypeHandler(userType);
        return handler.menu(username);
        // if (userType.equals("0")){ //业主
        //     //查询业主的权限信息
        //     LiveUser liveUser = liveUserService.loadUser(username);
        //     List<Menu> menuList = menuService.getMenuListByUserIdForLiveUser(liveUser.getUserId());
        //     //只需要获取目录和菜单
        //     List<Menu> collect = menuList.stream().filter(item -> item != null && !item.getType().equals("2")).collect(Collectors.toList());
        //     //组装路由数据
        //     List<RouterVO> list = MakeMenuTree.makeRouter(collect,0L);
        //     return Msg.success("查询成功",list);
        // }else {
        //     //查询业主的权限信息
        //     User user = userService.loadUser(username);
        //     List<Menu> menuList = menuService.getMenuListByUserId(user.getUserId());
        //     //只需要获取目录和菜单
        //     List<Menu> collect = menuList.stream().filter(item -> item != null && !item.getType().equals("2")).collect(Collectors.toList());
        //     //组装路由数据
        //     List<RouterVO> list = MakeMenuTree.makeRouter(collect,0L);
        //     return Msg.success("查询成功",list);
        // }
    }

    /**
     * 获取用户信息
     * */
    @GetMapping("/getInfo")
    public Msg getInfo(User user, HttpServletRequest request){
        //从头部获取token
        String token = request.getHeader("token");
        //获取用户类型
        Claims claims = jwtUtils.getClaimsFromToken(token);
        String userType = (String) claims.get("userType");
        LoginTypeHandler handler = userTypeHandlerFactory.getUserTypeHandler(userType);
        return handler.Info(user);
        // if (userType.equals("0")){//业主
        //     //根据业主id查询该登录用户
        //     LiveUser liveUser = liveUserService.getById(user.getUserId());
        //     //用户信息实体类
        //     UserInfo userInfo = new UserInfo();
        //     //获取用户id
        //     userInfo.setId(liveUser.getUserId());
        //     //获取用户姓名
        //     userInfo.setName(liveUser.getUsername());
        //     //获取用户头像
        //     userInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        //     //根据用户id查询,区分查询是哪一个
        //     //查询用户权限信息
        //     List<Menu> menuList = menuService.getMenuListByUserIdForLiveUser(liveUser.getUserId());
        //     List<String> collect = menuList.stream().filter(item -> item != null).map(item -> item.getMenuCode())
        //             .filter(item -> item != null).collect(Collectors.toList());
        //     //转成数组
        //     String[] strings = collect.toArray(new String[collect.size()]);
        //     userInfo.setRoles(strings);
        //     //返回成功的信息给前端
        //     return Msg.success("获取用户信息成功",userInfo);
        // }else { //物主
        //     //根据物主id查询该登录用户
        //     User user1 = userService.getById(user.getUserId());
        //     //用户信息实体类
        //     UserInfo userInfo = new UserInfo();
        //     //获取用户id
        //     userInfo.setId(user1.getUserId());
        //     //获取用户姓名
        //     userInfo.setName(user1.getUsername());
        //     //获取用户头像
        //     userInfo.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
        //     //根据用户id查询,区分查询是哪一个
        //     //查询用户权限信息
        //     List<Menu> menuList = menuService.getMenuListByUserId(user.getUserId());
        //     List<String> collect = menuList.stream().filter(item -> item != null).map(item -> item.getMenuCode())
        //             .filter(item -> item != null).collect(Collectors.toList());
        //     //转成数组
        //     String[] strings = collect.toArray(new String[collect.size()]);
        //     userInfo.setRoles(strings);
        //     //返回成功的信息给前端
        //     return Msg.success("获取用户信息成功",userInfo);
        // }
    }

    /**
     * 用户登录
     */
//    @PostMapping("/login")
//    public Msg login(@RequestBody LoginParm parm){
//        //判断前端表单传过来的值是否为空
//        if(StringUtils.isEmpty(parm.getUsername()) || StringUtils.isEmpty(parm.getPassword()) || StringUtils.isEmpty(parm.getUserType())){
//            return Msg.error("用户名、密码或用户类型不能为空!");
//        }
//        //查询用户信息，并对该用户进行md5解密
//        String password = DigestUtils.md5DigestAsHex(parm.getPassword().getBytes());
//        //条件构造器
//        QueryWrapper<User> query = new QueryWrapper<>();
//        query.lambda().eq(User::getLoginName,parm.getUsername())
//                .eq(User::getPassword,password);
//        //查询语句
//        User one = userService.getOne(query);
//        if(one == null){
//            return Msg.error("用户名、密码或用户类型错误!");
//        }
//        //如果用户存在，生成token返回给前端
//        String token = jwtUtils.generateToken(one.getUsername());
//        //获取生成的token的过期时间
//        Long expireTime =  jwtUtils.getExpireTime(token,jwtUtils.getSecret());
//        LoginResult result = new LoginResult();
//        result.setUserId(one.getUserId());
//        result.setToken(token);
//        result.setExpireTime(expireTime);
//        return Msg.success("登录成功",result);
//    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public Msg login(@RequestBody LoginParm parm){
        //判断前端表单传过来的值是否为空
        if(StringUtils.isEmpty(parm.getUsername()) || StringUtils.isEmpty(parm.getPassword()) || StringUtils.isEmpty(parm.getUserType())){
            return Msg.error("用户名、密码或用户类型不能为空!");
        }
        String encode = passwordEncoder.encode("123456");
        //spring-security需要的token
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(parm.getUsername()+":"+parm.getUserType(),parm.getPassword());
        Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        SecurityContextHolder.getContext().setAuthentication(authenticate);
        LoginTypeHandler handler = userTypeHandlerFactory.getUserTypeHandler(parm.getUserType());
        return handler.login(parm,authenticate);
        // if (parm.getUserType().equals("0")){
        //     LiveUser user = (LiveUser) authenticate.getPrincipal();
        //     //如果用户存在，生成token返回给前端
        //     String token = jwtUtils.generateToken(parm.getUsername(),parm.getUserType());
        //     //获取生成的token的过期时间
        //     Long expireTime =  jwtUtils.getExpireTime(token,jwtUtils.getSecret());
        //     LoginResult result = new LoginResult();
        //     result.setUserId(user.getUserId());
        //     result.setToken(token);
        //     result.setExpireTime(expireTime);
        //     return Msg.success("登录成功",result);
        // }else {
        //     User user1 = (User) authenticate.getPrincipal();
        //     //如果用户存在，生成token返回给前端
        //     String token = jwtUtils.generateToken(parm.getUsername(),parm.getUserType());
        //     //获取生成的token的过期时间
        //     Long expireTime =  jwtUtils.getExpireTime(token,jwtUtils.getSecret());
        //     LoginResult result = new LoginResult();
        //     result.setUserId(user1.getUserId());
        //     result.setToken(token);
        //     result.setExpireTime(expireTime);
        //     return Msg.success("登录成功",result);
        // }
    }

    //新增员工
    @PostMapping
    @PreAuthorize("hasAuthority('sys:user:add')")
    public Msg addUser(@RequestBody  @Valid User user){
        if(StringUtils.isNotEmpty(user.getUsername())){
            //判断登陆名 的唯一性
            QueryWrapper<User> query = new QueryWrapper<>();
            query.lambda().eq(User::getUsername,user.getUsername());
            User one = userService.getOne(query);
            if (one != null){
                return Msg.error("登录名已经被占用!", 500);
            }
        }
        if(StringUtils.isNotEmpty(user.getUsername())){
            //判断登陆名 的唯一性
            QueryWrapper<User> query = new QueryWrapper<>();
            query.lambda().eq(User::getLoginName,user.getLoginName());
            User one = userService.getOne(query);
            if (one != null){
                return Msg.error("姓名已经被占用!", 500);
            }
        }
        //如果密码存在，加密md5
        if(StringUtils.isNotEmpty(user.getPassword())){
//            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        userService.save(user);
        return Msg.success("保存员工成功");
    }


    //编辑员工
    @PutMapping
    @PreAuthorize("hasAuthority('sys:user:edit')")
    public Msg editUser(@RequestBody User user){
        if(StringUtils.isNotEmpty(user.getUsername())){
            //判断登陆名 的唯一性
            QueryWrapper<User> query = new QueryWrapper<>();
            query.lambda().eq(User::getUsername,user.getUsername());
            User one = userService.getOne(query);
            if (one != null){
                return Msg.error("登录名已经被占用!", 500);
            }
        }
        //如果密码存在，加密md5
        if(StringUtils.isNotEmpty(user.getPassword())){
//            user.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
            user.setPassword(passwordEncoder.encode(user.getPassword()));
        }
        boolean b = userService.updateById(user);
        if (b){
            return Msg.success("编辑员工成功");
        }else {
            return Msg.error("编辑员工失败");
        }
    }

    //删除员工
    @DeleteMapping("/{userId}")
    @PreAuthorize("hasAuthority('sys:user:delete')")
    public Msg deleteUser(@PathVariable("userId") Long userId){
        QueryWrapper<UserRole> queryWrapper = new QueryWrapper();
        queryWrapper.lambda().eq(UserRole::getUserId,userId);
        userRoleService.remove(queryWrapper);
        boolean b = userService.removeById(userId);
        if (b){
            return Msg.success("删除员工成功");
        }else {
            return Msg.error("删除员工失败");
        }
    }

    @GetMapping("/list")
    public Msg list(UserParm parms){
        IPage<User> list = userService.list(parms);
        list.getRecords().stream().forEach(item -> item.setPassword(""));
        return Msg.success("查询成功",list);
    }

    //根据用户id查询角色id
    @GetMapping("/getRoleByUserId")
    public Msg getRoleByUserId(UserRole userRole){
        UserRole roleByUserId = userService.getRoleByUserId(userRole);
        return Msg.success("查询成功",roleByUserId);
    }

    //重新分配角色
    @PostMapping("/saveRole")
    public Msg saveRole(@RequestBody UserRole userRole){
        userService.saveRole(userRole);
        return Msg.success("分配角色成功!");
    }


}
